package com.witmore.neutron.ai.mcp.server.trading.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.witmore.neutron.ai.mcp.server.trading.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 股票财务分析服务
 * 专注于基于财务报表的股票分析
 * 
 * @author 豆子高
 * @date 2025-01-20
 */
@Slf4j
@Service
public class StockAnalysisService {

    @Autowired
    private AkshareService akshareService;

    /**
     * 线程池用于并发获取数据
     */
    private final ExecutorService executorService = Executors.newFixedThreadPool(6);

    /**
     * 收集股票财务数据进行分析
     * 
     * @param stockCode 股票代码 (如: "SH600519" 或 "000001")
     * @return 财务分析报告
     */
    public StockAnalysisReportDTO collectStockFinancialDataForAnalysis(String stockCode) {
        log.info("开始收集股票财务数据用于分析: {}", stockCode);

        StockAnalysisReportDTO report = new StockAnalysisReportDTO();
        report.setStockCode(stockCode);
        report.setAnalysisTime(LocalDateTime.now());

        try {
            // 转换股票代码格式
            String emStockCode = convertToEmFormat(stockCode);
            String thsStockCode = convertToThsFormat(stockCode);
            String sinaStockCode = convertToSinaFormat(stockCode);

            // 并发获取财务报表数据
            CompletableFuture<StockFinancialDataDTO> financialFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return getStockFinancialData(emStockCode, thsStockCode, sinaStockCode);
                } catch (Exception e) {
                    log.error("获取财务数据失败: {}", e.getMessage());
                    return new StockFinancialDataDTO();
                }
            }, executorService);

            CompletableFuture<List<StockResearchReportDTO>> researchFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return getStockResearchReports(stockCode);
                } catch (Exception e) {
                    log.error("获取研报数据失败: {}", e.getMessage());
                    return new ArrayList<>();
                }
            }, executorService);

            CompletableFuture<String> basicInfoFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return akshareService.stockIndividualInfoEm(emStockCode);
                } catch (Exception e) {
                    log.error("获取基本信息失败: {}", e.getMessage());
                    return "{}";
                }
            }, executorService);

            // 等待所有数据获取完成
            CompletableFuture.allOf(financialFuture, researchFuture, basicInfoFuture).join();

            // 设置收集到的数据
            report.setFinancialData(financialFuture.get());
            report.setResearchReports(researchFuture.get());

            // 解析基本信息获取股票名称
            String basicInfo = basicInfoFuture.get();
            report.setStockName(parseStockNameFromBasicInfo(basicInfo));

            log.info("股票财务数据收集完成: {} - 研报{}条", 
                    stockCode, report.getResearchReports().size());

        } catch (Exception e) {
            log.error("收集股票财务数据时发生错误: {}", e.getMessage(), e);
        }

        return report;
    }

    /**
     * 转换为东方财富格式
     * 如: "000001" -> "SZ000001", "600519" -> "SH600519"
     */
    private String convertToEmFormat(String stockCode) {
        if (stockCode.startsWith("SH") || stockCode.startsWith("SZ")) {
            return stockCode;
        }
        
        if (stockCode.startsWith("6")) {
            return "SH" + stockCode;
        } else if (stockCode.startsWith("0") || stockCode.startsWith("3")) {
            return "SZ" + stockCode;
        }
        
        return stockCode;
    }

    /**
     * 转换为同花顺格式
     * 如: "SH600519" -> "600519", "SZ000001" -> "000001"
     */
    private String convertToThsFormat(String stockCode) {
        if (stockCode.startsWith("SH") || stockCode.startsWith("SZ")) {
            return stockCode.substring(2);
        }
        return stockCode;
    }

    /**
     * 转换为新浪格式
     * 如: "600519" -> "sh600519", "000001" -> "sz000001"
     */
    private String convertToSinaFormat(String stockCode) {
        String code = stockCode;
        if (stockCode.startsWith("SH")) {
            return "sh" + stockCode.substring(2);
        } else if (stockCode.startsWith("SZ")) {
            return "sz" + stockCode.substring(2);
        } else if (stockCode.startsWith("6")) {
            return "sh" + stockCode;
        } else if (stockCode.startsWith("0") || stockCode.startsWith("3")) {
            return "sz" + stockCode;
        }
        return code.toLowerCase();
    }

    /**
     * 获取股票财务数据
     * 从多个数据源获取完整的财务报表数据
     */
    private StockFinancialDataDTO getStockFinancialData(String emStockCode, String thsStockCode, String sinaStockCode) {
        StockFinancialDataDTO financialData = new StockFinancialDataDTO();
        financialData.setStockCode(emStockCode);
        financialData.setDataTimestamp(LocalDateTime.now().toString());

        try {
            // 并发获取多个数据源的财务报表
            CompletableFuture<Void> emDataFuture = CompletableFuture.runAsync(() -> {
                try {
                    // 东方财富-资产负债表
                    String balanceSheetReport = akshareService.getStockBalanceSheetByReportEm(emStockCode);
                    parseEmBalanceSheet(balanceSheetReport, financialData);

                    // 东方财富-利润表
                    String profitSheetReport = akshareService.getStockProfitSheetByReportEm(emStockCode);
                    parseEmProfitSheet(profitSheetReport, financialData);

                    // 东方财富-现金流量表
                    String cashFlowReport = akshareService.getStockCashFlowSheetByReportEm(emStockCode);
                    parseEmCashFlowSheet(cashFlowReport, financialData);

                    financialData.setDataSource("东方财富");
                } catch (Exception e) {
                    log.warn("从东方财富获取财务数据失败: {}", e.getMessage());
                }
            }, executorService);

            CompletableFuture<Void> thsDataFuture = CompletableFuture.runAsync(() -> {
                try {
                    // 同花顺-按报告期数据作为补充
                    String thsBalanceSheet = akshareService.getStockFinancialDebtThs(thsStockCode, "按报告期");
                    parseThsBalanceSheet(thsBalanceSheet, financialData);

                    String thsProfitSheet = akshareService.getStockFinancialBenefitThs(thsStockCode, "按报告期");
                    parseThsProfitSheet(thsProfitSheet, financialData);

                    String thsCashFlowSheet = akshareService.getStockFinancialCashThs(thsStockCode, "按报告期");
                    parseThsCashFlowSheet(thsCashFlowSheet, financialData);
                } catch (Exception e) {
                    log.warn("从同花顺获取财务数据失败: {}", e.getMessage());
                }
            }, executorService);

            CompletableFuture<Void> sinaDataFuture = CompletableFuture.runAsync(() -> {
                try {
                    // 新浪-三大报表作为备用数据源
                    String sinaBalanceSheet = akshareService.getStockFinancialReportSina(sinaStockCode, "资产负债表");
                    parseSinaFinancialData(sinaBalanceSheet, financialData, "资产负债表");

                    String sinaProfitSheet = akshareService.getStockFinancialReportSina(sinaStockCode, "利润表");
                    parseSinaFinancialData(sinaProfitSheet, financialData, "利润表");

                    String sinaCashFlowSheet = akshareService.getStockFinancialReportSina(sinaStockCode, "现金流量表");
                    parseSinaFinancialData(sinaCashFlowSheet, financialData, "现金流量表");
                } catch (Exception e) {
                    log.warn("从新浪获取财务数据失败: {}", e.getMessage());
                }
            }, executorService);

            // 等待所有数据获取完成
            CompletableFuture.allOf(emDataFuture, thsDataFuture, sinaDataFuture).join();

            // 计算衍生财务指标
            calculateDerivedRatios(financialData);

        } catch (Exception e) {
            log.error("获取财务数据失败: {}", e.getMessage());
        }

        return financialData;
    }

    /**
     * 获取股票研报
     */
    private List<StockResearchReportDTO> getStockResearchReports(String stockCode) {
        List<StockResearchReportDTO> reports = new ArrayList<>();
        
        try {
            String researchData = akshareService.getStockResearchReportEm(stockCode);
            reports = parseResearchReports(researchData);
        } catch (Exception e) {
            log.warn("获取研报数据失败: {}", e.getMessage());
        }

        return reports;
    }

    // ==================== 财务数据解析方法 ====================

    /**
     * 解析东方财富资产负债表数据
     */
    private void parseEmBalanceSheet(String balanceSheetJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(balanceSheetJson) && !balanceSheetJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(balanceSheetJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 存储原始数据
                    Map<String, Object> rawData = new HashMap<>();
                    latestData.forEach(rawData::put);
                    financialData.setBalanceSheetData(rawData);
                    
                    // 提取关键指标
                    financialData.setReportPeriod(latestData.getString("REPORTDATE"));
                    financialData.setTotalAssets(safeGetBigDecimal(latestData, "TOTALASSETS"));
                    financialData.setCurrentAssets(safeGetBigDecimal(latestData, "TOTALCURRENTASSETS"));
                    financialData.setTotalLiabilities(safeGetBigDecimal(latestData, "TOTALLIABILITY"));
                    financialData.setCurrentLiabilities(safeGetBigDecimal(latestData, "TOTALCURRENTLIABILITY"));
                    financialData.setShareholdersEquity(safeGetBigDecimal(latestData, "TOTALSHEQUITY"));
                    financialData.setParentShareholdersEquity(safeGetBigDecimal(latestData, "PARENTSHEQUITY"));
                }
            }
        } catch (Exception e) {
            log.error("解析东方财富资产负债表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析东方财富利润表数据
     */
    private void parseEmProfitSheet(String profitSheetJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(profitSheetJson) && !profitSheetJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(profitSheetJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 存储原始数据
                    Map<String, Object> rawData = new HashMap<>();
                    latestData.forEach(rawData::put);
                    financialData.setProfitSheetData(rawData);
                    
                    // 提取关键指标
                    financialData.setTotalRevenue(safeGetBigDecimal(latestData, "TOTALOPERATEREVE"));
                    financialData.setOperatingRevenue(safeGetBigDecimal(latestData, "OPERATEREVE"));
                    financialData.setOperatingCost(safeGetBigDecimal(latestData, "OPERATECOST"));
                    financialData.setOperatingProfit(safeGetBigDecimal(latestData, "OPERATEPROFIT"));
                    financialData.setTotalProfit(safeGetBigDecimal(latestData, "TOTALPROFIT"));
                    financialData.setNetProfit(safeGetBigDecimal(latestData, "NETPROFIT"));
                    financialData.setParentNetProfit(safeGetBigDecimal(latestData, "PARENTNETPROFIT"));
                    financialData.setBasicEarningsPerShare(safeGetBigDecimal(latestData, "BASICEPS"));
                    financialData.setDilutedEarningsPerShare(safeGetBigDecimal(latestData, "DILUTEDEPS"));
                }
            }
        } catch (Exception e) {
            log.error("解析东方财富利润表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析东方财富现金流量表数据
     */
    private void parseEmCashFlowSheet(String cashFlowJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(cashFlowJson) && !cashFlowJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(cashFlowJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 存储原始数据
                    Map<String, Object> rawData = new HashMap<>();
                    latestData.forEach(rawData::put);
                    financialData.setCashFlowSheetData(rawData);
                    
                    // 提取关键指标
                    financialData.setOperatingCashFlow(safeGetBigDecimal(latestData, "NETOPERATECASHFLOW"));
                    financialData.setInvestingCashFlow(safeGetBigDecimal(latestData, "NETINVESTCASHFLOW"));
                    financialData.setFinancingCashFlow(safeGetBigDecimal(latestData, "NETFINANCECASHFLOW"));
                    financialData.setNetCashFlow(safeGetBigDecimal(latestData, "NETCASHFLOW"));
                    financialData.setEndingCashBalance(safeGetBigDecimal(latestData, "ENDCASHEQUIVALENTS"));
                }
            }
        } catch (Exception e) {
            log.error("解析东方财富现金流量表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析同花顺资产负债表数据 (作为补充数据源)
     */
    private void parseThsBalanceSheet(String thsJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(thsJson) && !thsJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(thsJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 如果东方财富数据缺失，用同花顺数据补充
                    if (financialData.getTotalAssets() == null) {
                        financialData.setTotalAssets(safeGetBigDecimal(latestData, "资产总计"));
                    }
                    if (financialData.getTotalLiabilities() == null) {
                        financialData.setTotalLiabilities(safeGetBigDecimal(latestData, "负债合计"));
                    }
                }
            }
        } catch (Exception e) {
            log.warn("解析同花顺资产负债表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析同花顺利润表数据 (作为补充数据源)
     */
    private void parseThsProfitSheet(String thsJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(thsJson) && !thsJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(thsJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 如果东方财富数据缺失，用同花顺数据补充
                    if (financialData.getOperatingRevenue() == null) {
                        financialData.setOperatingRevenue(safeGetBigDecimal(latestData, "营业收入"));
                    }
                    if (financialData.getNetProfit() == null) {
                        financialData.setNetProfit(safeGetBigDecimal(latestData, "净利润"));
                    }
                }
            }
        } catch (Exception e) {
            log.warn("解析同花顺利润表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析同花顺现金流量表数据 (作为补充数据源)
     */
    private void parseThsCashFlowSheet(String thsJson, StockFinancialDataDTO financialData) {
        try {
            if (StringUtils.hasText(thsJson) && !thsJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(thsJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 如果东方财富数据缺失，用同花顺数据补充
                    if (financialData.getOperatingCashFlow() == null) {
                        financialData.setOperatingCashFlow(safeGetBigDecimal(latestData, "经营活动产生的现金流量净额"));
                    }
                }
            }
        } catch (Exception e) {
            log.warn("解析同花顺现金流量表失败: {}", e.getMessage());
        }
    }

    /**
     * 解析新浪财务数据 (作为备用数据源)
     */
    private void parseSinaFinancialData(String sinaJson, StockFinancialDataDTO financialData, String reportType) {
        try {
            if (StringUtils.hasText(sinaJson) && !sinaJson.equals("{}")) {
                JSONArray dataArray = JSONArray.parseArray(sinaJson);
                if (!dataArray.isEmpty()) {
                    JSONObject latestData = dataArray.getJSONObject(0);
                    
                    // 根据报表类型解析不同字段，作为备用数据源
                    switch (reportType) {
                        case "资产负债表":
                            if (financialData.getTotalAssets() == null) {
                                financialData.setTotalAssets(safeGetBigDecimal(latestData, "流动资产"));
                            }
                            break;
                        case "利润表":
                            if (financialData.getOperatingRevenue() == null) {
                                financialData.setOperatingRevenue(safeGetBigDecimal(latestData, "流动资产"));
                            }
                            break;
                        case "现金流量表":
                            // 新浪现金流量表数据处理
                            break;
                    }
                }
            }
        } catch (Exception e) {
            log.warn("解析新浪{}失败: {}", reportType, e.getMessage());
        }
    }

    /**
     * 计算衍生财务比率
     */
    private void calculateDerivedRatios(StockFinancialDataDTO financialData) {
        try {
            // 计算资产负债率
            if (financialData.getTotalAssets() != null && financialData.getTotalLiabilities() != null) {
                BigDecimal debtRatio = financialData.getTotalLiabilities()
                        .divide(financialData.getTotalAssets(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                financialData.setDebtToAssetRatio(debtRatio);
            }

            // 计算流动比率
            if (financialData.getCurrentAssets() != null && financialData.getCurrentLiabilities() != null 
                && financialData.getCurrentLiabilities().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal currentRatio = financialData.getCurrentAssets()
                        .divide(financialData.getCurrentLiabilities(), 4, RoundingMode.HALF_UP);
                financialData.setCurrentRatio(currentRatio);
            }

            // 计算毛利率
            if (financialData.getOperatingRevenue() != null && financialData.getOperatingCost() != null 
                && financialData.getOperatingRevenue().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal grossMargin = financialData.getOperatingRevenue().subtract(financialData.getOperatingCost())
                        .divide(financialData.getOperatingRevenue(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                financialData.setGrossProfitMargin(grossMargin);
            }

            // 计算净利润率
            if (financialData.getNetProfit() != null && financialData.getOperatingRevenue() != null 
                && financialData.getOperatingRevenue().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal netMargin = financialData.getNetProfit()
                        .divide(financialData.getOperatingRevenue(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                financialData.setNetProfitMargin(netMargin);
            }

            // 计算ROA
            if (financialData.getNetProfit() != null && financialData.getTotalAssets() != null 
                && financialData.getTotalAssets().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal roa = financialData.getNetProfit()
                        .divide(financialData.getTotalAssets(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                financialData.setReturnOnAssets(roa);
            }

            // 计算ROE
            if (financialData.getNetProfit() != null && financialData.getShareholdersEquity() != null 
                && financialData.getShareholdersEquity().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal roe = financialData.getNetProfit()
                        .divide(financialData.getShareholdersEquity(), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"));
                financialData.setReturnOnEquity(roe);
            }

        } catch (Exception e) {
            log.error("计算衍生财务比率失败: {}", e.getMessage());
        }
    }

    /**
     * 安全获取BigDecimal值
     */
    private BigDecimal safeGetBigDecimal(JSONObject jsonObject, String key) {
        try {
            Object value = jsonObject.get(key);
            if (value == null) {
                return null;
            }
            if (value instanceof Number) {
                return new BigDecimal(value.toString());
            }
            if (value instanceof String) {
                String strValue = (String) value;
                if (StringUtils.hasText(strValue) && !strValue.equals("--") && !strValue.equals("-")) {
                    return new BigDecimal(strValue);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 解析研报数据
     */
    private List<StockResearchReportDTO> parseResearchReports(String researchJson) {
        List<StockResearchReportDTO> reports = new ArrayList<>();
        
        try {
            if (StringUtils.hasText(researchJson) && !researchJson.equals("{}")) {
                JSONArray researchArray = JSONArray.parseArray(researchJson);
                
                for (Object item : researchArray) {
                    JSONObject reportObj = (JSONObject) item;
                    StockResearchReportDTO report = new StockResearchReportDTO();
                    
                    report.setTitle(reportObj.getString("报告名称"));
                    report.setInstitution(reportObj.getString("机构"));
                    report.setRating(reportObj.getString("东财评级"));
                    report.setPublishDate(reportObj.getString("日期"));
                    report.setUrl(reportObj.getString("报告PDF链接"));
                    
                    reports.add(report);
                }
            }
        } catch (Exception e) {
            log.error("解析研报数据失败: {}", e.getMessage());
        }
        
        return reports;
    }

    /**
     * 从基本信息中解析股票名称
     */
    private String parseStockNameFromBasicInfo(String basicInfoJson) {
        try {
            if (StringUtils.hasText(basicInfoJson) && !basicInfoJson.equals("{}")) {
                JSONArray infoArray = JSONArray.parseArray(basicInfoJson);
                for (Object item : infoArray) {
                    JSONObject infoObj = (JSONObject) item;
                    if ("股票简称".equals(infoObj.getString("item"))) {
                        return infoObj.getString("value");
                    }
                }
            }
        } catch (Exception e) {
            log.error("解析股票名称失败: {}", e.getMessage());
        }
        return "";
    }
}
